package com.example.dragcontentviewdemo.activity.ui.adapter;

import android.animation.Animator;
import android.animation.TimeInterpolator;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class DragGestureListenerImpl implements View.OnTouchListener{
    private static final String TAG = "BubbleGestureListener";
    private static final float CONSTANT_MIN_DISTANCE_TO_DELETE_VIEW = 100.f;
    private float mFirstX,mFirstY,mLastX,mLastY;

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        int action = event.getActionMasked();
        boolean result = false;
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                result = handleActionDown(v, event);
                break;
            case MotionEvent.ACTION_MOVE:
                result = handleActionMove(v, event);
                break;
            case MotionEvent.ACTION_UP:
                result = handleActionUp(v, event);
                break;
            case MotionEvent.ACTION_CANCEL:
                result = handleActionCancel(v, event);
            default:
                break;
        }
        return result;
    }

    private boolean handleActionDown(View v, MotionEvent ev) {
        mFirstX = ev.getRawX();
        mFirstY = ev.getRawY();
        mLastX = mFirstX;
        mLastY = mFirstY;

        return true;
    }

    private boolean handleActionCancel(View v, MotionEvent ev) {
        debugLog("ACTION CANCEL isInsideView: "+isInsideView(v, ev));
        debugEvent(ev);
        debugViewBound(v);
        return handleActionUp(v, ev);
    }

    private boolean handleActionMove(View v, MotionEvent ev) {
        float offsetX = ev.getRawX() - mFirstX;
        float offsetY = ev.getRawY() - mFirstY;

        /*
        bug: 左右拖动正常，上下拖动时，该view的可触控范围没有随着view的位移而改变
         */
        v.setTranslationY(offsetY);
        v.setTranslationX(offsetX);

        mLastX = ev.getRawX();
        mLastY = ev.getRawY();

        debugEvent(ev);
        debugViewBound(v);

        return true;
    }

    private boolean handleActionUp(View v, MotionEvent ev) {
        //判断移动距离是否超过阈值，超过则remove掉这个view
        float offsetX = v.getTranslationX();
        float offsetY = v.getTranslationY();

        float distance = (float) Math.sqrt( offsetX * offsetX + offsetY * offsetY);

        if ( distance > CONSTANT_MIN_DISTANCE_TO_DELETE_VIEW) {
            debugLog("ACTION UP isInsideView: "+isInsideView(v, ev));
            v.animate().scaleX(0.01f).scaleY(0.01f).alpha(0.f)
                .setDuration(200).setListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {

                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    v.setVisibility(View.GONE);
                }

                @Override
                public void onAnimationCancel(Animator animation) {

                }

                @Override
                public void onAnimationRepeat(Animator animation) {

                }
            }); //暂时魔法值，届时修改
        }
        else {
            v.animate().translationX(0).translationY(0);
        }
        return true;
    }

    private boolean isInsideView(View v,MotionEvent event){
        float x = event.getRawX();
        float y = event.getRawY();

        int left = v.getLeft();
        int right = v.getRight();
        int top = v.getTop();
        int bottom = v.getBottom();

        return x > left && x < right && y > top && y < bottom;
    }

    private void debugLog(String msg){
        Log.d(TAG, msg);
    }

    private void debugViewBound(View view){
        StringBuilder builder = new StringBuilder();
        builder.append("View {")
                .append(" left: ").append(view.getLeft()).append(",")
                .append(" right: ").append(view.getRight()).append(",")
                .append(" top: ").append(view.getTop()).append(",")
                .append(" bottom: ").append(view.getBottom()).append(",")
                .append(" x: ").append(view.getX()).append(",").append("y: ").append(view.getY())
                .append("}");
        debugLog(builder.toString());
    }

    private void debugEvent(MotionEvent event){
        StringBuilder builder = new StringBuilder();
        builder.append("event{ ")
                .append(" X:").append(event.getX()).append(",")
                .append(" Y:").append(event.getY()).append(",")
                .append(" RawX:").append(event.getRawX()).append(",")
                .append(" RawY:").append(event.getRawY()).append(",")
                .append(" }");
        debugLog(builder.toString());
    }
}
